#include"head.h"
#include"common.h"
struct KernelResponse exMsg(void *smsg, unsigned int slen) {
	struct sockaddr_nl local;
	struct sockaddr_nl kpeer;
	struct KernelResponse *rsp;
	struct cmdRequest *req;
	void *mem;
	int dlen, kpeerlen = sizeof(struct sockaddr_nl);
	
	// init socket
	int skfd = socket(PF_NETLINK, SOCK_RAW, 17);
	if (skfd < 0) {
		printf("socket can not create a netlink socket\n");
		// rsp.code = ERROR_CODE_EXCHANGE;
		return *rsp;
	}
	// bind
	memset(&local, 0, sizeof(local));
	local.nl_family = AF_NETLINK;
	local.nl_pid = getpid();
	local.nl_groups = 0;
	
	if (bind(skfd, (struct sockaddr *) &local, sizeof(local)) != 0) {
		printf("socket bind() error\n");
		close(skfd);
		return *rsp;
	}


	memset(&kpeer, 0, sizeof(kpeer));
	kpeer.nl_family = AF_NETLINK;
	kpeer.nl_pid = 0;
	kpeer.nl_groups = 0;

	// set send msg
	struct nlmsghdr *message=(struct nlmsghdr *)malloc(NLMSG_SPACE(slen));
	if(!message) {
		printf("[exchangeMsg] message malloc fail");
		close(skfd);
		// rsp.code = ;
		return *rsp;
	}
	memset(message, '\0', NLMSG_SPACE(slen));
	message->nlmsg_len = NLMSG_SPACE(slen);
	message->nlmsg_flags = 0;
	message->nlmsg_type = 0;
	message->nlmsg_seq = 0;
	message->nlmsg_pid = local.nl_pid;
	memcpy(NLMSG_DATA(message), smsg, slen);
	req=NLMSG_DATA(message);
	


	// send msg
	if (!sendto(skfd, message, message->nlmsg_len, 0, (struct sockaddr *) &kpeer, sizeof(kpeer))) {
		printf(" sendto fail");
		close(skfd);
		 free(message);
		// rsp.code = ERROR_CODE_EXCHANGE;
		return *rsp;
	}

	// recv msg
	struct nlmsghdr *nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)*sizeof(uint8_t));
	if (!nlh) {
		printf("nlh malloc fail");
		close(skfd);
		free(message);
		// rsp.code = ERROR_CODE_EXCHANGE;
		return *rsp;
	}

	if (!recvfrom(skfd, nlh, NLMSG_SPACE(MAX_PAYLOAD), 0, (struct sockaddr *) &kpeer, (socklen_t *)&kpeerlen)) {
		printf(" recvfrom fail");
		close(skfd);
		free(message);
		free(nlh);
		// rsp.code = ERROR_CODE_EXCHANGE;
		return *rsp;
	}
	
	dlen = nlh->nlmsg_len - NLMSG_SPACE(0);
	mem = malloc(dlen);
	if(!(mem)) {
		printf("dmsg malloc fail");
		close(skfd);
		free(message);
		free(nlh);
		return *rsp;
	}
	
	
        memset(mem, 0, dlen);

        memcpy(mem, NLMSG_DATA(nlh), dlen);

		rsp=(struct KernelResponse*)mem;
		rsp->data=mem+sizeof(struct KernelResponse);
	
        // rsp->rsplen = dlen - sizeof(struct KernelResponse)-1;
        // if(rsp.code < 0) {
        //     // rsp.code = ERROR_CODE_EXCHANGE;
        // }
	if (rsp->arrlen==0)
	{
		fwrite((char*)rsp->data, 1, rsp->rsplen, stdout);
	}
	
       
     

		
	close(skfd);
	free(message);
	free(nlh);
	return *rsp;
}